#ifndef G_CODE_NUMBER_FORMAT_H
#define G_CODE_NUMBER_FORMAT_H

#include <assert.h>

class GCodeNumberFormat
{
protected:
	long int significand_;
	unsigned char exponent_;
public:
	GCodeNumberFormat(long int significand, char exponent)
		: significand_(significand), exponent_(1 - exponent)
	{
		assert(-99999999 <= significand);
		assert(significand <= 99999999);
		assert(-8 <= exponent);
		assert(exponent <= 1);
	}
	GCodeNumberFormat(long int int32 = 0)
		: significand_(0), exponent_(0)
	{
		unsigned long int dword = (unsigned long int) int32;
		unsigned long int significand = dword >> 4;
		unsigned char exponent = (unsigned char) dword;
		if (significand & 0x08000000)
			significand |= 0xF0000000;
		exponent &= 0x0F;
		significand_ = (long int) significand;
		exponent_ = exponent;
	}
	long int getSignificand()
	{
		return significand_;
	}
	void setSignificand(long int significand)
	{
		assert(-99999999 <= significand);
		assert(significand <= 99999999);
		significand_ = significand;
	}
	char getExponent()
	{
		return exponent_ > 0 ? 1 - (char) exponent_ : 0;
	}
	void setExponent(char exponent)
	{
		assert(-8 <= exponent);
		assert(exponent <= 1);
		exponent_ = (unsigned char) 1 - exponent;
	}
	operator long int()
	{
		unsigned long int significand = (unsigned long int) significand_;
		unsigned char exponent = exponent_;
		unsigned long int dword = (significand << 4) | (exponent & 0x0F);
		return (long int) dword;
	}
	unsigned char getLeading()
	{
		int numDigits;
		long int divisor;

		divisor = 1;
		for (numDigits = 0; numDigits <= 8; numDigits++) {
			if (significand_ / divisor == 0)
				break;
			divisor *= 10;
		}
		if (exponent_ > 0)
			numDigits -= exponent_ - 1;
		return numDigits < 0 ? 0 : numDigits;
	}
	unsigned char getTrailing()
	{
		return exponent_ > 0 ? exponent_ - 1 : 0;
	}
	bool isNegative()
	{
		return significand_ < 0;
	}
	bool isFloat()
	{
		return exponent_ > 0;
	}
};

#endif
